home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / Wave / WavesWorld / Source / IBPalettes / WW3DKit / RIBDisk.m < prev    next >
Encoding:
Text File  |  1995-05-13  |  9.3 KB  |  354 lines

  1. // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
  2. // see COPYRIGHT for reuse legalities
  3. //
  4.  
  5. #import "RIBDisk.h"
  6. #import <stdio.h>
  7.  
  8.  
  9. @implementation RIBDisk
  10.  
  11.  
  12. + initialize { return [RIBDisk setVersion:1], self; }
  13.  
  14. - (BOOL)hasBoundingBox { return YES; }
  15.  
  16. - init
  17. {
  18.   [super init];
  19.  
  20.   height = 1.0;
  21.   radius = 1.0;
  22.   
  23.   return self;
  24. }
  25.  
  26. - setHeight:(RtFloat)newHeight 
  27.      radius:(RtFloat)newRadius 
  28.      thetaMax:(RtFloat)newThetaMax 
  29.      n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
  30.      printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
  31. {  
  32.    height = newHeight;
  33.    radius = newRadius;
  34.    thetaMax = newThetaMax;
  35.    [self setN:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];
  36.  
  37.    dirtyBoundingBox = TRUE;
  38.    return self;
  39. }
  40.  
  41. - setHeight:(RtFloat)newHeight { height = newHeight; dirtyBoundingBox = TRUE; return self; }
  42. - setRadius:(RtFloat)newRadius { radius = newRadius; dirtyBoundingBox = TRUE; return self; }
  43.  
  44. - (RtFloat)height { return height; }
  45. - (RtFloat)radius { return radius; }
  46.  
  47.  
  48. - calculateBoundingBoxStartingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
  49. {
  50.   if (thetaMax >= 180.0)
  51.   {   boundingBox[0] =  -1.0 * radius;
  52.   }
  53.   else  // less than 180
  54.   {  if (thetaMax >= 90.0)
  55.      {  boundingBox[0] =  -1.0 * radius * (RtFloat)sin((double)(toRadians((thetaMax - 90.0))));
  56.      }
  57.      else
  58.      {  //boundingBox[0] =  radius * (RtFloat)sin((double)(toRadians(thetaMax)));
  59.         boundingBox[0] = 0.0;  // this is not true if zMax or abs(zMin) is less than radius
  60.      }
  61.   }
  62.   boundingBox[1] = radius;
  63.  
  64.   if (thetaMax >= 270.0)
  65.   {  boundingBox[2] = -1.0 * radius;
  66.      boundingBox[3] = radius;
  67.   }
  68.   else
  69.   {  if (thetaMax >= 180.0)
  70.      {  boundingBox[2] = radius * sin((double)(toRadians((thetaMax))));
  71.         boundingBox[3] = radius;
  72.      }
  73.      else
  74.      {  if (thetaMax >= 90.0)
  75.         {  boundingBox[2] = 0.0;
  76.            boundingBox[3] = radius;
  77.         }
  78.         else
  79.         {  boundingBox[2] = 0.0;
  80.            boundingBox[3] = radius * sin((double)(toRadians((thetaMax))));
  81.         }
  82.      }
  83.   }
  84.  
  85.   if (height < 0.0)
  86.   {  boundingBox[5] = 0.0;
  87.      boundingBox[4] = height;
  88.   }
  89.   else
  90.   {  boundingBox[4] = 0.0;
  91.      boundingBox[5] = height;
  92.   }
  93.  
  94.   dirtyBoundingBox = FALSE; 
  95.  
  96.   return self;
  97. }
  98.  
  99.  
  100. - (BOOL)isMoot
  101. {
  102.   if (!radius) { return YES; }
  103.  
  104.   return [super isMoot];
  105. }
  106.  
  107. - (BOOL)theSameAs:otherRIBCommand
  108. {
  109.   if (radius != [otherRIBCommand radius])
  110.   {  return NO;
  111.   }
  112.   if (height != [otherRIBCommand height])
  113.   {  return NO;
  114.   }
  115.  
  116.   return [super theSameAs:otherRIBCommand];
  117. }
  118.  
  119. - renderSelf:(WW3DCamera *)camera  startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
  120. {
  121.   RiDiskV(height, radius, thetaMax, n, tokens, parms);
  122.  
  123.   return self;
  124. }
  125.  
  126. - (unsigned long int)maxSampleBandwidth {  return ([super maxSampleBandwidth] + (unsigned long int)(3 * sizeof(RtFloat))); }
  127.  
  128. - (BOOL)isLerpable { return YES; }
  129.  
  130. // note: because we've made the WWSampleList "safe" for having
  131. // multiple samples with the same data, it's perfectly valid to return
  132. // yourself or b
  133. - lerpWith:b by:(float)uValue
  134. {
  135.    id      newMe = nil;
  136.    RtFloat radiusA, heightA, thetaMaxA;
  137.    RtFloat radiusB, heightB, thetaMaxB;
  138.  
  139.  
  140.    if (([self class] != [b class]) || (uValue <= 0.0))
  141.    {  return self;
  142.    }
  143.  
  144.    if (uValue >= 1.0)
  145.    {  return b;
  146.    }
  147.  
  148.    newMe = [super lerpWith:b by:uValue]; // this makes a copy for us
  149.  
  150.    // okay, now do the specific stuff for this class
  151.    radiusA = [self radius];
  152.    radiusB = [b radius];
  153.    [newMe setRadius:(radiusA + ((radiusB - radiusA) * uValue))]; 
  154.    heightA = [self height];
  155.    heightB = [b height];
  156.    [newMe setHeight:(heightA + ((heightB - heightA) * uValue))];
  157.    thetaMaxA = [self thetaMax];
  158.    thetaMaxB = [b thetaMax];
  159.    [newMe setThetaMax:(thetaMaxA + ((thetaMaxB - thetaMaxA) * uValue))];
  160.  
  161.    return newMe;
  162. }
  163.  
  164.  
  165. - lerpSelfWith:b by:(float)uValue
  166. {
  167.    RtFloat radiusA, heightA, thetaMaxA;
  168.    RtFloat radiusB, heightB, thetaMaxB;
  169.  
  170.  
  171.    if (([self class] != [b class]) || (uValue <= 0.0))
  172.    {  return self;
  173.    }
  174.  
  175.    if (uValue >= 1.0)
  176.    {  return b;
  177.    }
  178.  
  179.    [super lerpSelfWith:b by:uValue]; // this makes a copy for us
  180.  
  181.    // okay, now do the specific stuff for this class
  182.    radiusA = [self radius];
  183.    radiusB = [b radius];
  184.    [self setRadius:(radiusA + ((radiusB - radiusA) * uValue))]; 
  185.    heightA = [self height];
  186.    heightB = [b height];
  187.    [self setHeight:(heightA + ((heightB - heightA) * uValue))];
  188.    thetaMaxA = [self thetaMax];
  189.    thetaMaxB = [b thetaMax];
  190.    [self setThetaMax:(thetaMaxA + ((thetaMaxB - thetaMaxA) * uValue))];
  191.  
  192.    return self;
  193. }
  194.  
  195. - writeEve:(NXStream *)stream atTabLevel:(int)tab
  196. {
  197.    int  i;
  198.  
  199.  
  200.    for (i = 0; i < tab; i++)
  201.    {  NXPrintf(stream, "\t");
  202.    }
  203.    NXPrintf(stream, "Disk %f %f %f ", height, radius, thetaMax);
  204.    [super writeParameterList:stream];
  205.    return self;
  206. }
  207.  
  208. - writeInventorAtTime:(float)currentTime to:(NXStream *)stream atTabLevel:(int)tab
  209. {
  210.    RtFloat umax;
  211.    RtFloat uknots[12];
  212.    RtFloat uk[12] = {0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1.0, 1.0, 1.0};
  213.    RtFloat vknots[4] = {0.0, 0.0, 1.0, 1.0};
  214.    RtFloat xuspline[9][2] = {{1.0, 0.0}, {M_SQRT1_2, -M_SQRT1_2}, {0.0, -1.0}, {-M_SQRT1_2, -M_SQRT1_2}, 
  215.                              {-1.0, 0.0}, {-M_SQRT1_2, M_SQRT1_2},  {0.0, 1.0}, {M_SQRT1_2, M_SQRT1_2}, {1.0, 0.0}};
  216.    RtFloat yuspline[9][2] = {{0.0, 1.0}, {M_SQRT1_2, M_SQRT1_2}, {1.0, 0.0}, {M_SQRT1_2, -M_SQRT1_2}, {0.0, -1.0}, 
  217.                            {-M_SQRT1_2, -M_SQRT1_2}, {-1.0, 0.0}, {-M_SQRT1_2, M_SQRT1_2}, {0.0, 1.0}};
  218.    RtFloat zwuspline[9] = {1.0, M_SQRT1_2, 1.0, M_SQRT1_2, 1.0, M_SQRT1_2, 1.0, M_SQRT1_2, 1.0};
  219.    int i, j, k;
  220.    RtPoint point1, point2;
  221.  
  222.  
  223.    point1[0] = [self radius];
  224.    point1[1] = 0.0;
  225.    point1[2] = [self height];
  226.    point2[0] = 0.0;
  227.    point2[1] = 0.0;
  228.    point2[2] = [self height];
  229.  
  230.    umax = [self thetaMax] / 360.0;
  231.    for (i=0; i<12; i++)
  232.    {  uknots[i] = uk[i] / umax;
  233.    }
  234.  
  235.    for (i = 0; i < tab; i++)
  236.    {  NXPrintf(stream, "\t");
  237.    }
  238.    NXPrintf(stream, "# ");
  239.    [self writeEve:stream atTabLevel:0];
  240.    NXPrintf(stream, "\n");
  241.  
  242.    for (i = 0; i < tab; i++)
  243.    {  NXPrintf(stream, "\t");
  244.    }
  245.    NXPrintf(stream, "# since Inventor doesn't directly support quadrics in any terribly useful way (sigh), we turn it into a NURBS surface:\n");
  246.  
  247.    for (i = 0; i < tab; i++)
  248.    {  NXPrintf(stream, "\t");
  249.    }
  250.    NXPrintf(stream, "Separator {\n");
  251.  
  252.    for (i = 0; i < (tab+1); i++)  {  NXPrintf(stream, "\t"); }
  253.    NXPrintf(stream, "Coordinate4 {\n");
  254.    for (i = 0; i < (tab+2); i++) {  NXPrintf(stream, "\t"); }
  255.    NXPrintf(stream, "point [");
  256.  
  257.    for (j=0; j<9; j++)
  258.    {  if (!j)
  259.       {  NXPrintf(stream, 
  260.           "%f %f %f %f,\n", 
  261.           (point1[0] * xuspline[j][0] + point1[1] * xuspline[j][1]),
  262.           (point1[0] * yuspline[j][0] + point1[1] * yuspline[j][1]),
  263.           (point1[2] * zwuspline[j]),
  264.           (zwuspline[j]));
  265.       }
  266.       else
  267.       {  NXPrintf(stream, 
  268.           "       %f %f %f %f,\n", 
  269.           (point1[0] * xuspline[j][0] + point1[1] * xuspline[j][1]),
  270.           (point1[0] * yuspline[j][0] + point1[1] * yuspline[j][1]),
  271.           (point1[2] * zwuspline[j]),
  272.           (zwuspline[j]));
  273.       }
  274.       for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  275.    }
  276.  
  277.    for (j=0; j<8; j++)
  278.    {  NXPrintf(stream, 
  279.            "       %f %f %f %f,\n", 
  280.            (point2[0] * xuspline[j][0] + point2[1] * xuspline[j][1]),
  281.            (point2[0] * yuspline[j][0] + point2[1] * yuspline[j][1]),
  282.            (point2[2] * zwuspline[j]),
  283.            (zwuspline[j]));
  284.       for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  285.    }
  286.    NXPrintf(stream, 
  287.         "       %f %f %f %f]\n", 
  288.         (point2[0] * xuspline[j][0] + point2[1] * xuspline[j][1]),
  289.         (point2[0] * yuspline[j][0] + point2[1] * yuspline[j][1]),
  290.         (point2[2] * zwuspline[j]),
  291.         (zwuspline[j]));
  292.  
  293.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  294.    NXPrintf(stream, "}\n");
  295.  
  296.    for (k = 0; k < (tab+1); k++) {  NXPrintf(stream, "\t"); }
  297.    NXPrintf(stream, "NurbsSurface {\n");
  298.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  299.    NXPrintf(stream, "numUControlPoints 9\n");
  300.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  301.    NXPrintf(stream, "numVControlPoints 2\n");
  302.  
  303.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  304.    NXPrintf(stream, "uKnotVector [");
  305.    for (i=0; i<11; i++)
  306.    {    NXPrintf(stream, "%f, ", uknots[i]);
  307.    }
  308.    NXPrintf(stream, "%f]\n", uknots[i]);
  309.  
  310.    for (k = 0; k < (tab+2); k++) {  NXPrintf(stream, "\t"); }
  311.    NXPrintf(stream, "vKnotVector [");
  312.    for (i=0; i<3; i++)
  313.    {    NXPrintf(stream, "%f, ", vknots[i]);
  314.    }
  315.    NXPrintf(stream, "%f]\n", vknots[i]);
  316.    for (k = 0; k < (tab+1); k++) {  NXPrintf(stream, "\t"); }
  317.    NXPrintf(stream, "}\n");
  318.    for (k = 0; k < tab; k++) {  NXPrintf(stream, "\t"); }
  319.    NXPrintf(stream, "}\n");
  320.  
  321.    return self;
  322. }
  323.  
  324. #define typeVector "ff"
  325. #define typeValues &height, &radius
  326.  
  327. - read:(NXTypedStream*)stream 
  328. {
  329.     int version;
  330.     [super read:stream];
  331.  
  332.     version = NXTypedStreamClassVersion(stream,"RIBDisk");
  333.     if (version == 0) NXReadTypes(stream,"i",&version), version=1;
  334.     if (version == 1)
  335.     {  NXReadTypes(stream,typeVector,typeValues);
  336.     } 
  337.     else 
  338.     {
  339.     }
  340.     return self;
  341. }
  342.  
  343. - write:(NXTypedStream*)stream 
  344. {
  345.     [super write:stream];
  346.  
  347.     NXWriteTypes(stream,typeVector, typeValues);
  348.  
  349.     return self;
  350. }
  351.  
  352.  
  353. @end
  354.